package com.stud.common.utils.oss;

import cn.hutool.core.codec.Base64Decoder;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.*;
import com.stud.common.enums.FileBusinessType;
import com.stud.common.exception.file.FileException;
import com.stud.common.utils.StringUtils;
import com.stud.common.utils.file.FileUploadUtils;
import com.stud.common.utils.file.FileUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.Base64;
import java.util.Date;
import java.util.Objects;
import java.util.UUID;

/**
 * @author Stud
 * @title XXXXX
 * @desription XXXXX
 * @data 2022-09-08 18:05
 */
@Slf4j
public class OssUtil {
    private static String endpoint = "https://oss-cn-zhangjiakou.aliyuncs.com";
    private static String accessKeyId = "LTAI5tQA2a8n7RoYZSw7pVX4";
    private static String accessKeySecret = "OOB6zYQ3JLnnfu7f7U8tZ9s9EW5Dyx";
    private static final OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    private static String bucketName = "bc-p2-file";
    private static String filePath = "https://bc-p2-file.oss-cn-zhangjiakou.aliyuncs.com/";

    public static boolean doesBucketExist() {
        return ossClient.doesBucketExist(bucketName);
    }

    /**
     * 返回fileKey,后续通过fileKey查找对应文件
     *
     * @param base64
     * @param fileBusinessType
     * @return
     */
    public static String putObject(String base64, String ass, FileBusinessType fileBusinessType) {
        if (StringUtils.isBlank(base64)) {
            return null;
        }
        Base64Decoder.decode(base64);

        byte[] bytes = Base64Decoder.decode(base64);
        InputStream in = new ByteArrayInputStream(bytes);

        return putObject(in, ass, fileBusinessType);
    }


    /**
     * 返回fileKey,后续通过fileKey查找对应文件
     *
     * @param inputStream
     * @param ass
     * @param fileBusinessType
     * @return
     */
    public static String putObject(InputStream inputStream, String ass, FileBusinessType fileBusinessType) {
        String fileKey = fileBusinessType.getFolder() + UUID.randomUUID() + ass;
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, fileKey, inputStream);
        ossClient.putObject(putObjectRequest);
        return fileKey;
    }

    /**
     * 返回fileKey,后续通过fileKey查找对应文件
     *
     * @param file
     * @param fileBusinessType
     * @return
     */
    public static String putObject(MultipartFile file, FileBusinessType fileBusinessType) {
        InputStream inputStream;
        try {
            inputStream = file.getInputStream();
        } catch (IOException e) {
            throw new FileException("获得文件流失败");
        }

        String fileKey = fileBusinessType.getFolder() + FileUploadUtils.extractFilename_(file);
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, fileKey, inputStream);
        ossClient.putObject(putObjectRequest);
        return fileKey;
    }

    /**
     * 返回fileKey,后续通过fileKey查找对应文件
     *
     * @param file
     * @param fileBusinessType
     * @return
     */
    public static String uploadObject(MultipartFile file, FileBusinessType fileBusinessType) {
        InputStream inputStream;
        try {
            inputStream = file.getInputStream();
        } catch (IOException e) {
            throw new FileException("获得文件流失败");
        }

        int pointIndex = file.getOriginalFilename().lastIndexOf(".");

        String fileName = file.getOriginalFilename().substring(0, pointIndex);
        String fileAss = file.getOriginalFilename().substring(pointIndex);

        String fileKey = fileBusinessType.getFolder() + fileName + "-" + UUID.randomUUID() + fileAss;
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, fileKey, inputStream);
        ossClient.putObject(putObjectRequest);
        return fileKey;
    }

    /**
     * 下载文件
     *
     * @param fileKey
     * @return
     */
    public static void getObject(String fileKey, OutputStream outputStream) {
        GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, fileKey);
        OSSObject ossObject = ossClient.getObject(getObjectRequest);
        if (Objects.isNull(ossObject.getObjectContent())) {
            throw new FileException("获取文件失败");
        }
        try {
            FileUtils.writeBytes(ossObject.getObjectContent(), outputStream);
        } catch (IOException e) {
            throw new FileException("下载文件失败");
        }
    }

    /**
     * 下载文件
     *
     * @param fileKey
     * @return
     */
    public static String showBase64Img(String fileKey) {
        GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, fileKey);
        OSSObject ossObject = ossClient.getObject(getObjectRequest);
        if (Objects.isNull(ossObject.getObjectContent())) {
            throw new FileException("获取文件失败");
        }

        // 创建byte数组输出对象
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        int buffSize = 1000;
        byte[] buff = new byte[buffSize];
        try {
            int rc;
            InputStream binaryStream = ossObject.getObjectContent();
            while ((rc = binaryStream.read(buff, 0, buffSize)) > 0) {
                byteArrayOutputStream.write(buff, 0, rc);
            }
        } catch (IOException e) {
            throw new FileException("图片无法预览");
        }
        byte[] byteArray = byteArrayOutputStream.toByteArray();
        return Base64.getEncoder().encodeToString(byteArray);
    }

    /**
     * 查询文件列表
     *
     * @param prefix     文件名模糊查询 根据前缀查询
     * @param nextMarker objectListing.getNextMarker();
     * @param maxKeys    显示多少条
     * @return
     */
    public static ObjectListing listObjects(String prefix, String nextMarker, Integer maxKeys) {
        ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);

        if (!StringUtils.isBlank(prefix)) {
            listObjectsRequest.setPrefix(prefix);
        }
        if (!StringUtils.isBlank(nextMarker)) {
            listObjectsRequest.setMarker(nextMarker);
        }
        if (maxKeys != null) {
            listObjectsRequest.setMaxKeys(maxKeys);
        }

        ObjectListing objectListing = ossClient.listObjects(listObjectsRequest);
        objectListing.getNextMarker();
        return objectListing;
    }

    /**
     * 查询文件全路径,默认有效时间30分钟
     *
     * @param fileKey
     * @return
     */
    public static String generatePresignedUrl(String fileKey) {
        GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, fileKey);
        Date expiration = new Date(System.currentTimeMillis() + 3000 * 1000);
        generatePresignedUrlRequest.setExpiration(expiration);
        String url = ossClient.generatePresignedUrl(generatePresignedUrlRequest).toString();
        return url;
    }

    /**
     * 删除文件
     *
     * @param fileKey
     * @return
     */
    public static void deleteObject(String fileKey) {
        GenericRequest genericRequest = new GenericRequest(bucketName, fileKey);
        ossClient.deleteObject(genericRequest);
    }

    /**
     * @param fileKey
     * @return
     */
    public static String fileKey2Url(String fileKey) {
        return filePath + fileKey;
    }

}
